package com.ruoyi.system.controller;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Validator;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.RoleUtils;
import com.ruoyi.common.utils.SheetHandler;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.temple.DirectTemple;
import com.ruoyi.system.domain.temple.IndirectTemple;
import com.ruoyi.system.service.*;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 间接费用Controller
 *
 * @author ruoyi
 * @date 2024-04-04
 */
@RestController
@RequestMapping("/system/indirect")
@Slf4j
public class IndirectController extends BaseController {
    @Autowired
    private IProjectInfoService projectInfoService;
    @Autowired
    private IProcurementDetailService procurementDetailService;
    @Autowired
    private ILaborService laborService;
    @Autowired
    private IDirectService directService;
    @Autowired
    private IIndirectService indirectService;
    @Autowired
    private IOutputService outputService;
    @Autowired
    protected Validator validator;

    /**
     * 查询间接费用列表
     */
    @PreAuthorize("@ss.hasPermi('system:indirect:list')")
    @GetMapping("/list")
    public Map<String, Object> list(Indirect indirect) {
        startPage();

        if (!RoleUtils.hasPermission(projectInfoService.getRoleIdsByUserId(getUserId()))) {
            indirect.setProjectCode(projectInfoService.getProjectCodeByUserId(getUserId()));
        } else {
            indirect.setProjectCode(null);
        }

        List<Indirect> indirectList = indirectService.selectIndirectList(indirect);

        List<String> projectCodeList = projectInfoService.getProjectCodes(indirect.getAreaId());

        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("projectCodeList", projectCodeList);
        dataMap.put("dataList", getDataTable(indirectList));

        return dataMap;
    }

    /**
     * 导出间接费用列表
     */
    @PreAuthorize("@ss.hasPermi('system:indirect:export')")
    @Log(title = "间接费用", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Indirect indirect) {
        List<Indirect> list = indirectService.selectIndirectList(indirect);
        ExcelUtil<Indirect> util = new ExcelUtil<Indirect>(Indirect.class);
        util.exportExcel(response, list, "间接费用数据");
    }

    /**
     * 获取间接费用详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:indirect:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(indirectService.selectIndirectById(id));
    }

    /**
     * 新增间接费用
     */
    @PreAuthorize("@ss.hasPermi('system:indirect:add')")
    @Log(title = "间接费用", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Indirect indirect) {

        if (indirectService.checkIndirectByProjectCodeAndNameId(indirect.getProjectCode(), indirect.getNameId()) == 0) {
            indirect.setProjectCode(projectInfoService.getProjectCodeByUserId(getUserId()));
            indirect.setCreateBy(getUsername());
            indirect.setCreateTime(DateUtils.getNowDate());

            indirect.setDateNumber(DateUtils.getMonth());
            projectInfoService.updateProjectNumber(DateUtils.getMonth(), indirect.getProjectCode());

            return toAjax(indirectService.insertIndirect(indirect));
        } else {
            return AjaxResult.warn("该项目已存在该费用项");
        }


    }

    /**
     * 修改间接费用
     */
    @PreAuthorize("@ss.hasPermi('system:indirect:edit')")
    @Log(title = "间接费用", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Indirect indirect) {
        indirect.setUpdateBy(getUsername());
        indirect.setUpdateTime(DateUtils.getNowDate());

        return toAjax(indirectService.updateIndirect(indirect));
    }

    /**
     * 删除间接费用
     */
    @PreAuthorize("@ss.hasPermi('system:indirect:remove')")
    @Log(title = "间接费用", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(indirectService.deleteIndirectByIds(ids));
    }


    /**
     * 导入间接费用
     */
    @Log(title = "间接费用导入", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('system:indirect:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, @RequestParam("areaId") String areaStr,
                                 @RequestParam("dateNumber") String dateNumber) throws Exception {
        log.info("areaId: " + areaStr);
        Integer areaId = Integer.parseInt(areaStr);

        ExcelUtil<Indirect> indirectExcelUtil = new ExcelUtil<Indirect>(Indirect.class);
        if (file.isEmpty()) {
            return error("文件为空");
        }
        InputStream inputStream = file.getInputStream();

        List<Indirect> indirectList = indirectExcelUtil.importExcel(inputStream, 2);

        if (StringUtils.isNull(indirectList) || indirectList.size() == 0) {
            throw new ServiceException("导入数据不能为空！");

        }
        LocalDate currentDate = LocalDate.now();
        int currentYear = currentDate.getYear();
        int currentMonth = currentDate.getMonthValue();
        String operName = getUsername();
        //
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        int count;
        for (Indirect indirect : indirectList) {
            indirect.setAreaId(areaId);
            indirect.setProjectCode(projectInfoService.getProjectCodeByUserId(getUserId()));
            if (indirect.getDateNumber() != null) {
                String entityDate = indirect.getDateNumber();
                LocalDate entityLocalDate = LocalDate.parse(entityDate + "-01"); // 添加一个固定的日期作为日期格式化的补充，这里假设为每月的第一天
                int entityYear = entityLocalDate.getYear();
                int entityMonth = entityLocalDate.getMonthValue();
                if (currentYear == entityYear && currentMonth == entityMonth) {
                    indirect.setDateNumber(DateUtils.getMonth());
                } else {
                    indirect.setDateNumber(dateNumber);
                    log.info("前端 dateNumber：" + dateNumber);
                }
                try {
                    // 验证是否存在该条数据
                    Indirect query = new Indirect();
                    System.out.println(query);
                    query.setProjectCode(indirect.getProjectCode());
                    query.setNameId(indirect.getNameId());
                    query.setDateNumber(indirect.getDateNumber());
                    count = indirectService.countIndirectByProjectCodeAndNumber(query);
                    BeanValidators.validateWithException(validator, indirect);
                    if (count != 0) {
                        indirect.setUpdateBy(operName);
                        indirect.setUpdateTime(DateUtils.getNowDate());
                        indirectService.updateIndirect(indirect);
                        successNum++;
                        successMsg.append("<br/>").append(successNum)
                                .append("、间接费用 ：").append(indirect.getIndirectName())
                                .append(" 更新成功");
                    } else {
                        indirect.setCreateBy(operName);
                        indirect.setCreateTime(DateUtils.getNowDate());
                        indirectService.insertIndirect(indirect);
                        successNum++;
                        successMsg.append("<br/>").append(successNum)
                                .append("、间接费用 ：").append(indirect.getIndirectName())
                                .append(" 导入成功");
                    }
                } catch (Exception e) {
                    failureNum++;
                    String msg = "<br/>" + failureNum + "、间接费用 ：" + indirect.getIndirectName()
                            + " 导入失败：";
                    failureMsg.append(msg).append(e.getMessage());
                    log.error(msg, e);
                }
            }
            if (failureNum > 0) {
                failureMsg.insert(0, "部分导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
                throw new ServiceException(failureMsg.toString());
            } else {
                successMsg.insert(0, "数据已全部导入成功！共 " + successNum + " 条，数据如下：");
            }

            inputStream.close();


        }
        return success(successMsg.toString());
    }


    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) throws IOException{
        // 创建 ExcelWriter 对象
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).relativeHeadRowIndex(2).build();

        // 设置表头样式
        WriteCellStyle headCellStyle = new WriteCellStyle();
        WriteFont headFont = new WriteFont();
        headFont.setFontHeightInPoints((short) 10); // 设置字体大小
        headCellStyle.setWriteFont(headFont);
        headCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 设置背景颜色
        headCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //垂直居中,水平居中
        headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        headCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        headCellStyle.setBorderLeft(BorderStyle.THIN);
        headCellStyle.setBorderTop(BorderStyle.THIN);
        headCellStyle.setBorderRight(BorderStyle.THIN);
        headCellStyle.setBorderBottom(BorderStyle.THIN);
        headCellStyle.setWrapped(true);

        // 创建自定义的内容样式
        WriteCellStyle contentCellStyle = new WriteCellStyle();
        WriteFont contentFont = new WriteFont();
        contentFont.setFontHeightInPoints((short) 10); // 设置字体大小
        contentCellStyle.setWriteFont(contentFont);
        contentCellStyle.setWrapped(true); // 设置文字过长时自动换行
        //垂直居中,水平居中
        contentCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentCellStyle.setBorderLeft(BorderStyle.THIN);
        contentCellStyle.setBorderTop(BorderStyle.THIN);
        contentCellStyle.setBorderRight(BorderStyle.THIN);
        contentCellStyle.setBorderBottom(BorderStyle.THIN);

        // 创建 模板 Excel
        WriteSheet indirectTemplate = EasyExcel.writerSheet(0,"间接费用")
                .head(IndirectTemple.class)
                .registerWriteHandler(new SheetHandler())
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle,contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short)40,(short)20)) // 简单的行高策略：头行高30，内容行高20
                .build();

        // 创建 模板 数据对象
        List<IndirectTemple> indirectTempleList = new ArrayList<>();
        indirectTempleList.add(new IndirectTemple());
        excelWriter.write(indirectTempleList, indirectTemplate);
        excelWriter.finish();

    }
}
